﻿/* 十六进制数据解析工具*/
namespace System.Helpers
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Text;
    
    public static class BC
    {
        private static Encoding _encoding = new UTF8Encoding(false, true);

        public static byte BCDToByte(byte num)
        {
            return (byte) (((num / 0x10) * 10) + (num % 0x10));
        }

        public static byte BCDToByte(byte[] buffer, int offset)
        {
            return (byte) (((buffer[offset] / 0x10) * 10) + (buffer[offset++] % 0x10));
        }

        public static byte BCDToByte(byte[] buffer, ref int offset)
        {
            return (byte) (((buffer[offset] / 0x10) * 10) + (buffer[offset++] % 0x10));
        }

        public static short BCDToInt16(short num)
        {
            byte num2 = (byte) (num >> 8);
            byte num3 = (byte) num;
            return (short) (((((num2 / 0x10) * 10) + (num2 % 0x10)) * 100) + (((num3 / 0x10) * 10) + (num3 % 0x10)));
        }

        public static short BCDToInt16(byte[] buffer, ref int offset)
        {
            return (short) (((((buffer[offset] / 0x10) * 10) + (buffer[offset++] % 0x10)) * 100) + (((buffer[offset] / 0x10) * 10) + (buffer[offset++] % 0x10)));
        }

        public static short BCDToInt16(byte[] buffer, int offset)
        {
            return (short) (((((buffer[offset] / 0x10) * 10) + (buffer[offset++] % 0x10)) * 100) + (((buffer[offset] / 0x10) * 10) + (buffer[offset++] % 0x10)));
        }

        public static int BCDToInt24(int num)
        {
            byte num2 = (byte) (num >> 0x10);
            byte num3 = (byte) (num >> 8);
            byte num4 = (byte) num;
            return ((((((num2 / 0x10) * 10) + (num2 % 0x10)) * 0x2710) + ((((num3 / 0x10) * 10) + (num3 % 0x10)) * 100)) + (((num4 / 0x10) * 10) + (num4 % 0x10)));
        }

        public static int BCDToInt24(byte[] buffer, int bufferOffset)
        {
            return ((((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 0x2710) + ((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 100)) + (((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)));
        }

        public static int BCDToInt24(byte[] buffer, ref int bufferOffset)
        {
            return ((((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 0x2710) + ((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 100)) + (((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)));
        }

        public static ushort BCDToUInt16(ushort num)
        {
            byte num2 = (byte) (num >> 8);
            byte num3 = (byte) num;
            return (ushort) (((((num2 / 0x10) * 10) + (num2 % 0x10)) * 100) + (((num3 / 0x10) * 10) + (num3 % 0x10)));
        }

        public static ushort BCDToUInt16(byte[] buffer, int bufferOffset)
        {
            return (ushort) (((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 100) + (((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)));
        }

        public static ushort BCDToUInt16(byte[] buffer, ref int bufferOffset)
        {
            return (ushort) (((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 100) + (((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)));
        }

        public static uint BCDToUInt24(uint num)
        {
            byte num2 = (byte) (num >> 0x10);
            byte num3 = (byte) (num >> 8);
            byte num4 = (byte) num;
            return (uint) ((((((num2 / 0x10) * 10) + (num2 % 0x10)) * 0x2710) + ((((num3 / 0x10) * 10) + (num3 % 0x10)) * 100)) + (((num4 / 0x10) * 10) + (num4 % 0x10)));
        }

        public static uint BCDToUInt24(byte[] buffer, int bufferOffset)
        {
            return (uint) ((((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 0x2710) + ((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 100)) + (((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)));
        }

        public static uint BCDToUInt24(byte[] buffer, ref int bufferOffset)
        {
            return (uint) ((((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 0x2710) + ((((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)) * 100)) + (((buffer[bufferOffset] / 0x10) * 10) + (buffer[bufferOffset++] % 0x10)));
        }
        /// <summary>
        /// 基于Buffer数组到无符号十进制数
        /// </summary>
        /// <param name="buffer">BCD字节数组</param>
        /// <param name="bufferOffset">数据开始位置</param>
        /// <returns></returns>
        public static uint BCDToUInt32(byte[] buffer, ref int bufferOffset)
        {
            return BCDToUInt32(ToUInt32Net(buffer, ref bufferOffset));
        }

        public static int BCDToUInt32(int num)
        {
            byte num2 = (byte) (num >> 0x18);
            byte num3 = (byte) (num >> 0x10);
            byte num4 = (byte) (num >> 8);
            byte num5 = (byte) num;
            return (((((((num2 / 0x10) * 10) + (num2 % 0x10)) * 0xf4240) + ((((num3 / 0x10) * 10) + (num3 % 0x10)) * 0x2710)) + ((((num4 / 0x10) * 10) + (num4 % 0x10)) * 100)) + (((num5 / 0x10) * 10) + (num5 % 0x10)));
        }

        public static uint BCDToUInt32(uint num)
        {
            byte num2 = (byte) (num >> 0x18);
            byte num3 = (byte) (num >> 0x10);
            byte num4 = (byte) (num >> 8);
            byte num5 = (byte) num;
            return (uint) (((((((num2 / 0x10) * 10) + (num2 % 0x10)) * 0xf4240) + ((((num3 / 0x10) * 10) + (num3 % 0x10)) * 0x2710)) + ((((num4 / 0x10) * 10) + (num4 % 0x10)) * 100)) + (((num5 / 0x10) * 10) + (num5 % 0x10)));
        }

        public static byte ByteToBCD(byte num)
        {
            return (byte) (((num / 10) * 0x10) + (num % 10));
        }

        public static ushort CharToInt16(byte[] buffer, ref int offset)
        {
            return (ushort) ((((buffer[offset++] - 0x30) * 10) + buffer[offset++]) - 0x30);
        }

        public static ushort CharToInt16(byte[] buffer, int offset)
        {
            return (ushort) ((((buffer[offset++] - 0x30) * 10) + buffer[offset++]) - 0x30);
        }

        public static uint CharToInt24(byte[] buffer, ref int offset)
        {
            return (uint) (((((buffer[offset++] - 0x30) * 100) + ((buffer[offset++] - 0x30) * 10)) + buffer[offset++]) - 0x30);
        }

        public static uint CharToInt24(byte[] buffer, int offset)
        {
            return (uint) (((((buffer[offset++] - 0x30) * 100) + ((buffer[offset++] - 0x30) * 10)) + buffer[offset++]) - 0x30);
        }

        public static uint CharToInt32(byte[] buffer, int offset)
        {
            return (uint) ((((((buffer[offset++] - 0x30) * 0x3e8) + ((buffer[offset++] - 0x30) * 100)) + ((buffer[offset++] - 0x30) * 10)) + buffer[offset++]) - 0x30);
        }

        public static uint CharToInt32(byte[] buffer, ref int offset)
        {
            return (uint) ((((((buffer[offset++] - 0x30) * 0x3e8) + ((buffer[offset++] - 0x30) * 100)) + ((buffer[offset++] - 0x30) * 10)) + buffer[offset++]) - 0x30);
        }

        public static byte CharToInt8(byte[] buffer, ref int offset)
        {
            return (byte) (buffer[offset++] - 0x30);
        }

        public static byte CharToInt8(byte[] buffer, int offset)
        {
            return (byte) (buffer[offset++] - 0x30);
        }

        public static int FindSymbol(byte[] buffer, byte[] symbol, int bufferStart = 0, int bufferEnd = -1, bool moveEnd = false, bool reverseFind = false, int index = 0)
        {
            if ((symbol != null) && (symbol.Length != 0))
            {
                int num3;
                if (buffer == null)
                {
                    return -1;
                }
                if ((bufferEnd < 0) || (bufferEnd > buffer.Length))
                {
                    bufferEnd = buffer.Length;
                }
                int num = 0;
                int num2 = 1;
                bool flag = true;
                if (reverseFind)
                {
                    num3 = bufferEnd - symbol.Length;
                    while (num3 >= bufferStart)
                    {
                        if (buffer[num3] != symbol[0])
                        {
                            num3--;
                            continue;
                        }
                        num2 = 1;
                        flag = true;
                        while (num2 < symbol.Length)
                        {
                            if (buffer[num3 + num2] != symbol[num2])
                            {
                                flag = false;
                                break;
                            }
                            num2++;
                        }
                        if (!flag)
                        {
                            num3--;
                        }
                        else
                        {
                            if (num != index)
                            {
                                num++;
                                num3 -= symbol.Length;
                                continue;
                            }
                            if (moveEnd)
                            {
                                return (num3 + symbol.Length);
                            }
                            return num3;
                        }
                    }
                }
                else
                {
                    bufferEnd = (bufferEnd - symbol.Length) + 1;
                    num3 = bufferStart;
                    while (num3 < bufferEnd)
                    {
                        if (buffer[num3] != symbol[0])
                        {
                            num3++;
                            continue;
                        }
                        num2 = 1;
                        flag = true;
                        while (num2 < symbol.Length)
                        {
                            if (buffer[num3 + num2] != symbol[num2])
                            {
                                flag = false;
                                break;
                            }
                            num2++;
                        }
                        if (!flag)
                        {
                            num3++;
                        }
                        else
                        {
                            if (num != index)
                            {
                                num++;
                                num3 += symbol.Length;
                                continue;
                            }
                            if (moveEnd)
                            {
                                return (num3 + symbol.Length);
                            }
                            return num3;
                        }
                    }
                }
            }
            return -1;
        }

        public static byte[] FromBCDString(string target)
        {
            return FromBCDString(target, 0, target.Length);
        }

        public static byte[] FromBCDString(string buffer, int start, int count)
        {
            if (buffer == null)
            {
                return Bytes.Empty.buffer;
            }
            bool flag = false;
            byte item = 0;
            int num2 = start + count;
            List<byte> list = new List<byte>(count / 2);
            while (start < num2)
            {
                byte num3 = (byte)buffer[start++];
                switch (num3)
                {
                    case 0x20:
                    case 13:
                    case 10:
                    case 9:
                        {
                            if (flag)
                            {
                                list.Add((byte)(item / 0x10));
                                flag = false;
                            }
                            continue;
                        }
                }
                byte num4 = 0;
                if ((num3 >= 0x30) && (num3 <= 0x39))
                {
                    num4 = (byte)(num3 - 0x30);
                }
                else if ((num3 >= 0x61) && (num3 <= 0x66))
                {
                    num4 = (byte)((num3 - 0x61) + 10);
                }
                else
                {
                    if ((num3 < 0x41) || (num3 > 70))
                    {
                        throw new ArgumentException("需要传入一个正确的BCD字符串，BCD字符串中只能包含 0-9 A-F a-f 和空格，回车 制表符!");
                    }
                    num4 = (byte)((num3 - 0x41) + 10);
                }
                if (!flag)
                {
                    item = (byte)(num4 * 0x10);
                    flag = true;
                }
                else
                {
                    item = (byte)(item + num4);
                    flag = false;
                    list.Add(item);
                }
            }
            if (flag)
            {
                list.Add((byte)(item / 0x10));
                flag = false;
            }
            return list.ToArray();
        }

        public static byte[] FromBCDString(byte[] buffer, int start, int count)
        {
            bool flag = false;
            byte item = 0;
            int num2 = start + count;
            List<byte> list = new List<byte>(count / 2);
            while (start < num2)
            {
                byte num3 = buffer[start++];
                switch (num3)
                {
                    case 0x20:
                    case 13:
                    case 10:
                    case 9:
                    {
                        if (flag)
                        {
                            list.Add((byte) (item / 0x10));
                            flag = false;
                        }
                        continue;
                    }
                }
                byte num4 = 0;
                if ((num3 >= 0x30) && (num3 <= 0x39))
                {
                    num4 = (byte) (num3 - 0x30);
                }
                else if ((num3 >= 0x61) && (num3 <= 0x66))
                {
                    num4 = (byte) ((num3 - 0x61) + 10);
                }
                else
                {
                    if ((num3 < 0x41) || (num3 > 70))
                    {
                        throw new ArgumentException("需要传入一个正确的BCD字符串，BCD字符串中只能包含 0-9 A-F a-f 和空格，回车 制表符!");
                    }
                    num4 = (byte) ((num3 - 0x41) + 10);
                }
                if (!flag)
                {
                    item = (byte) (num4 * 0x10);
                    flag = true;
                }
                else
                {
                    item = (byte) (item + num4);
                    flag = false;
                    list.Add(item);
                }
            }
            if (flag)
            {
                list.Add((byte) (item / 0x10));
                flag = false;
            }
            return list.ToArray();
        }

        public static byte[] FromCharString(string str)
        {
            byte[] buffer = new byte[str.Length];
            for (int i = 0; i < str.Length; i++)
            {
                buffer[i] = (byte) str[i];
            }
            return buffer;
        }

        public static byte[] FromCharString(byte[] str, int offset, int len)
        {
            byte[] buffer = new byte[len];
            for (int i = 0; i < len; i++)
            {
                buffer[i] = str[i + offset];
            }
            return buffer;
        }

        public static byte[] FromCharString(string str, int offset, int len)
        {
            byte[] buffer = new byte[len];
            for (int i = 0; i < len; i++)
            {
                buffer[i] = (byte) str[i + offset];
            }
            return buffer;
        }

        public static string GetBufferString(byte[] buffer, int offset, int len)
        {
            if (buffer == null)
            {
                return null;
            }
            string str = "";
            len += offset;
            while ((offset < len) && (offset < buffer.Length))
            {
                if (buffer[offset] != 0)
                {
                    str = str + ((char) buffer[offset]).ToString();
                }
                else
                {
                    str = str + "0";
                }
                offset++;
            }
            return str;
        }

        public static int GetByteCount(string content)
        {
            if (content == null)
            {
                content = string.Empty;
            }
            int num = _encoding.GetByteCount(content) + 1;
            if (num > 0x80)
            {
                num++;
            }
            return num;
        }

        public static byte[] GetBytes(string value)
        {
            byte[] buffer = new byte[GetByteCount(value)];
            Write(value, buffer);
            return buffer;
        }

        public static int GetSymbolCount(byte[] buffer, int dataStart, int dataEnd, params byte[] symbol)
        {
            if ((symbol == null) || (symbol.Length == 0))
            {
                return 0;
            }
            int bufferStart = FindSymbol(buffer, symbol, dataStart, dataEnd, true, false, 0);
            int num2 = 0;
            while (bufferStart != -1)
            {
                num2++;
                bufferStart = FindSymbol(buffer, symbol, bufferStart, dataEnd, true, false, 0);
            }
            return num2;
        }

        public static int GetSymbolCount(byte[] buffer, byte[] symbol, int dataStart = 0, int dataEnd = -1)
        {
            if ((symbol == null) || (symbol.Length == 0))
            {
                return 0;
            }
            if (dataEnd == -1)
            {
                dataEnd = buffer.Length;
            }
            int bufferStart = FindSymbol(buffer, symbol, dataStart, dataEnd, true, false, 0);
            int num2 = 0;
            while (bufferStart != -1)
            {
                num2++;
                bufferStart = FindSymbol(buffer, symbol, bufferStart, dataEnd, true, false, 0);
            }
            return num2;
        }

        public static bool IsBCDString(this string content)
        {
            foreach (char ch in content)
            {
                if (((((ch != ' ') && (ch != '\r')) && ((ch != '\n') && (ch != '\t'))) && (((ch < '0') || (ch > '9')) && ((ch < 'a') || (ch > 'f')))) && ((ch < 'A') || (ch > 'F')))
                {
                    return false;
                }
            }
            return true;
        }

        private static int Read7BitEncodedInt(byte[] buffer, ref int offset)
        {
            byte num;
            if ((offset < 0) || (offset >= buffer.Length))
            {
                return 0;
            }
            int num2 = 0;
            int num3 = 0;
            do
            {
                if (offset >= buffer.Length)
                {
                    return num2;
                }
                num = buffer[offset++];
                num2 |= (num & 0x7f) << num3;
                num3 += 7;
            }
            while ((num & 0x80) != 0);
            return num2;
        }

        public static bool ReadBit(byte source, int index)
        {
            return ((source & (((int) 1) << index)) > 0);
        }

        public static bool ReadBit(int source, int index)
        {
            return ((source & (((int) 1) << index)) > 0);
        }

        public static bool ReadBit(long source, int index)
        {
            return ((source & (((long) 1L) << index)) > 0L);
        }

        public static bool ReadBit(ulong source, int index)
        {
            return ((source & (((ulong) 1L) << index)) > 0L);
        }

        public static byte ReadByte(byte[] buffer, ref int offset)
        {
            return buffer[offset++];
        }

        public static byte ReadByte(byte[] buffer, int offset)
        {
            return buffer[offset++];
        }

        public static byte ReadByte(uint target, int index)
        {
            return (byte) ((target >> (index * 8)) & 0xff);
        }

        public static byte ReadByte(int target, int index)
        {
            return (byte) ((target >> (index * 8)) & 0xff);
        }

        public static byte ReadByte(char target, int index)
        {
            return (byte) ((target >> ((index * 8) & 0x1f)) & '\x00ff');
        }

        public static byte ReadByte(short target, int index)
        {
            return (byte) ((target >> (index * 8)) & 0xff);
        }

        public static byte ReadByte(long target, int index)
        {
            return (byte) ((target >> (index * 8)) & 0xffL);
        }

        public static byte ReadByte(ushort target, int index)
        {
            return (byte) ((target >> (index * 8)) & 0xff);
        }

        public static byte ReadByte(ulong target, int index)
        {
            return (byte) ((target >> (index * 8)) & ((ulong) 0xffL));
        }

        //public static byte[] ReplaceSymbol(byte[] buffer, byte[] symbol, byte[] replacment, int dataStart = 0, int dataEnd = -1, CreateNewArrayFlag createNewArray = (CreateNewArrayFlag)2, bool outerRangeValidate = false)
        //{
        //    byte[] buffer2;
        //    int num5;
        //    if (dataEnd == -1)
        //    {
        //        dataEnd = buffer.Length;
        //    }
        //    int num = GetSymbolCount(buffer, dataStart, dataEnd, symbol);
        //    if (num == 0)
        //    {
        //        switch (createNewArray)
        //        {
        //            case CreateNewArrayFlag.TRUE:
        //                buffer2 = new byte[buffer.Length];
        //                Array.Copy(buffer, buffer2, buffer.Length);
        //                return buffer2;

        //            case CreateNewArrayFlag.FALSE:
        //            case CreateNewArrayFlag.AUTO:
        //                return buffer;
        //        }
        //    }
        //    if (createNewArray == CreateNewArrayFlag.AUTO)
        //    {
        //        if (((buffer.Length - (symbol.Length * num)) + (replacment.Length * num)) >= buffer.Length)
        //        {
        //            createNewArray = CreateNewArrayFlag.TRUE;
        //        }
        //        else
        //        {
        //            createNewArray = CreateNewArrayFlag.FALSE;
        //        }
        //    }
        //    if (createNewArray == CreateNewArrayFlag.TRUE)
        //    {
        //        int num3;
        //        int num4;
        //        int destinationIndex = 0;
        //        if (outerRangeValidate)
        //        {
        //            num3 = 0;
        //            buffer2 = new byte[(buffer.Length - (symbol.Length * num)) + (replacment.Length * num)];
        //            num4 = buffer.Length - dataEnd;
        //            if (num4 > 0)
        //            {
        //                Array.Copy(buffer, dataEnd, buffer2, buffer2.Length - num4, num4);
        //            }
        //        }
        //        else
        //        {
        //            num3 = dataStart;
        //            buffer2 = new byte[((dataEnd - dataStart) - (symbol.Length * num)) + (replacment.Length * num)];
        //        }
        //        for (num5 = FindSymbol(buffer, symbol, dataStart, dataEnd, false, false, 0); num5 != -1; num5 = FindSymbol(buffer, symbol, num3, dataEnd, false, false, 0))
        //        {
        //            num4 = num5 - num3;
        //            Array.Copy(buffer, num3, buffer2, destinationIndex, num4);
        //            destinationIndex += num4;
        //            Array.Copy(replacment, 0, buffer2, destinationIndex, replacment.Length);
        //            destinationIndex += replacment.Length;
        //            num3 = num5 + symbol.Length;
        //        }
        //        if (num3 < dataEnd)
        //        {
        //            Array.Copy(buffer, num3, buffer2, destinationIndex, dataEnd - num3);
        //        }
        //        return buffer2;
        //    }
        //    num5 = FindSymbol(buffer, symbol, dataStart, dataEnd, false, false, 0);
        //    int bufferEnd = dataEnd;
        //    while (num5 != -1)
        //    {
        //        Array.Copy(buffer, (int) (num5 + symbol.Length), buffer, (int) (num5 + replacment.Length), (int) ((bufferEnd - num5) - symbol.Length));
        //        Array.Copy(replacment, 0, buffer, num5, replacment.Length);
        //        num5 = FindSymbol(buffer, symbol, num5 + replacment.Length, bufferEnd, false, false, 0);
        //    }
        //    return buffer;
        //}

        public static ulong Reverse(ulong num)
        {
            ulong num2 = 0L;
            int num4 = 0;
            for (int i = 7; i >= 0; i--)
            {
                byte num3 = (byte) ((num >> (8 * i)) & ((ulong) 0xffL));
                if ((num4 != 0) || (num3 != 0))
                {
                    num2 |= (ulong)(num3 << (8 * num4++));
                }
            }
            return num2;
        }

        public static void SetHigh(ref ushort target, byte high)
        {
            target = (ushort) (target & 0xff);
            target = (ushort) (target | ((ushort) (high << 8)));
        }

        public static void SetLow(ref ushort target, byte low)
        {
            target = (ushort) (target & 0xff00);
            target = (ushort) (target | low);
        }

        public static string ToBCDString(byte[] buffer)
        {
            return ToBCDString(buffer, null);
        }

        public static string ToBCDString(byte[] buffer, string split)
        {
            string str = "";
            for (int i = 0; i < buffer.Length; i++)
            {
                if (((i != 0) && (split != null)) && (split != string.Empty))
                {
                    str = str + split;
                }
                str = str + buffer[i].ToString("X2");
            }
            return str;
        }

        public static string ToBCDString(byte[] buffer, ref int actionStart, int len)
        {
            string str = "";
            for (int i = 0; (i < len) && (i < buffer.Length); i++)
            {
                str = str + buffer[actionStart++].ToString("X2");
            }
            return str;
        }

        public static string ToBCDString(byte[] buffer, int actionStart, int len, string split=null)
        {
            StringBuilder builder = new StringBuilder((len * 2) + ((split != null) ? (len * split.Length) : 0));
            for (int i = 0; (i < len) && (i < buffer.Length); i++)
            {
                if ((i != 0) && (split != null))
                {
                    builder.Append(split);
                }
                builder.Append(buffer[actionStart++].ToString("X2"));
            }
            return builder.ToString();
        }

        public static string ToBCDString(byte[] buffer, ref int actionStart, int len, string split)
        {
            StringBuilder builder = new StringBuilder((len * 2) + ((split != null) ? (len * split.Length) : 0));
            for (int i = 0; (i < len) && (i < buffer.Length); i++)
            {
                if ((i != 0) && (split != null))
                {
                    builder.Append(split);
                }
                builder.Append(buffer[actionStart++].ToString("X2"));
            }
            return builder.ToString();
        }

        public static bool ToBoolean(byte[] buffer)
        {
            return (buffer[0] > 0);
        }

        public static bool ToBoolean(byte[] buffer, ref int offset)
        {
            return (buffer[offset++] > 0);
        }

        public static bool ToBoolean(byte[] buffer, int offset)
        {
            return (buffer[offset++] > 0);
        }

        public static byte ToByte(byte[] buffer)
        {
            return buffer[0];
        }

        public static byte ToByte(byte[] buffer, ref int bufferOffset)
        {
            return buffer[bufferOffset++];
        }

        public static byte ToByte(byte[] buffer, int bufferOffset)
        {
            return buffer[bufferOffset];
        }

        public static byte[] ToBytes(string content)
        {
            if (content == null)
            {
                content = string.Empty;
            }
            int byteCount = _encoding.GetByteCount(content);
            int num2 = byteCount + ((byteCount > 0x80) ? 2 : 1);
            byte[] buffer = new byte[num2];
            int offset = 0;
            Write7BitEncodedInt(buffer, ref offset, byteCount);
            _encoding.GetBytes(content, 0, content.Length, buffer, offset);
            return buffer;
        }

        public static string ToCharString(byte[] buffer, ref int offst, int len)
        {
            StringBuilder builder = new StringBuilder(len);
            for (int i = 0; (i < len) && (i < buffer.Length); i++)
            {
                builder.Append((char) buffer[i + offst]);
            }
            offst += len;
            return builder.ToString();
        }

        public static string ToCharString(byte[] buffer, int offst, int len, int padLen, char padChar)
        {
            StringBuilder builder = new StringBuilder(len * 2);
            for (int i = 0; (i < len) && (i < buffer.Length); i++)
            {
                builder.Append(padChar);
                builder.Append((char) buffer[i + offst]);
            }
            return builder.ToString();
        }

        public static string ToCharString(byte[] buffer, int offst = 0, int len = -1, bool trimStartLines = false, bool fillZero = true, char fillChar = '.')
        {
            if (len == -1)
            {
                len = buffer.Length - offst;
            }
            if (trimStartLines)
            {
                int index = (offst + len) - 1;
                while (((offst > 0) && (offst <= index)) && (offst < buffer.Length))
                {
                    if ((buffer[offst] != 13) && (buffer[offst] != 10))
                    {
                        break;
                    }
                    offst++;
                }
                while ((index > offst) && (index < buffer.Length))
                {
                    if ((buffer[index] != 13) && (buffer[index] != 10))
                    {
                        break;
                    }
                    index--;
                }
                len = (index - offst) + 1;
            }
            StringBuilder builder = new StringBuilder(len);
            for (int i = 0; (i < len) && (i < buffer.Length); i++)
            {
                if (buffer[i + offst] == 0)
                {
                    if (!fillZero)
                    {
                        break;
                    }
                    builder.Append(fillChar);
                }
                else
                {
                    builder.Append((char) buffer[i + offst]);
                }
            }
            return builder.ToString();
        }

        public static DateTime ToDateTime(byte[] buffer, int bufferOffset)
        {
            return DateTime.FromOADate(BitConverter.ToDouble(buffer, bufferOffset));
        }

        public static DateTime ToDateTime(byte[] buffer, ref int bufferOffset)
        {
            double num = BitConverter.ToDouble(buffer, bufferOffset);
            bufferOffset += BitConverter.GetBytes(num).Length;
            return DateTime.FromOADate(num);
        }

        public static double ToDouble(byte[] buffer)
        {
            return BitConverter.ToDouble(buffer, 0);
        }

        public static double ToDouble(byte[] buffer, ref int bufferOffset)
        {
            double num = BitConverter.ToDouble(buffer, bufferOffset);
            bufferOffset += 8;
            return num;
        }

        public static double ToDouble(byte[] buffer, int bufferOffset)
        {
            return BitConverter.ToDouble(buffer, bufferOffset);
        }

        public static short ToInt16(byte[] buffer)
        {
            return (short) (buffer[0] | (buffer[1] << 8));
        }

        public static short ToInt16(byte[] buffer, int bufferOffset)
        {
            return (short) (buffer[bufferOffset] | (buffer[bufferOffset + 1] << 8));
        }

        public static short ToInt16(byte[] buffer, ref int bufferOffset)
        {
            return (short) (buffer[bufferOffset++] | (buffer[bufferOffset++] << 8));
        }

        public static short ToInt16Net(byte[] buffer, int bufferOffset)
        {
            return (short) ((buffer[bufferOffset] << 8) | buffer[bufferOffset + 1]);
        }

        public static short ToInt16Net(byte[] buffer, ref int bufferOffset)
        {
            return (short) ((buffer[bufferOffset++] << 8) | buffer[bufferOffset++]);
        }

        public static int ToInt32(byte[] buffer)
        {
            return (((buffer[0] | (buffer[1] << 8)) | (buffer[2] << 0x10)) | (buffer[3] << 0x18));
        }

        public static int ToInt32(byte[] buffer, ref int bufferOffset)
        {
            return (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
        }

        public static int ToInt32(byte[] buffer, int bufferOffset)
        {
            return (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
        }

        public static int ToInt32Net(byte[] buffer, ref int bufferOffset)
        {
            return ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
        }

        public static int ToInt32Net(byte[] buffer, int bufferOffset)
        {
            return ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
        }

        public static long ToInt64(byte[] buffer)
        {
            uint num = (uint) (((buffer[0] | (buffer[1] << 8)) | (buffer[2] << 0x10)) | (buffer[3] << 0x18));
            uint num2 = (uint) (((buffer[4] | (buffer[5] << 8)) | (buffer[6] << 0x10)) | (buffer[7] << 0x18));
            return (long) ((num2 << 0x20) | num);
        }

        public static long ToInt64(byte[] buffer, int bufferOffset)
        {
            uint num = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            uint num2 = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            return (long) ((num2 << 0x20) | num);
        }

        public static long ToInt64(byte[] buffer, ref int bufferOffset)
        {
            uint num = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            uint num2 = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            return (long) ((num2 << 0x20) | num);
        }

        public static long ToInt64Net(byte[] buffer, ref int bufferOffset)
        {
            uint num = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            uint num2 = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            return (long) (num2 | (num << 0x20));
        }

        public static long ToInt64Net(byte[] buffer, int bufferOffset)
        {
            uint num = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            uint num2 = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            return (long) (num2 | (num << 0x20));
        }

        public static float ToSingle(byte[] buffer)
        {
            return BitConverter.ToSingle(buffer, 0);
        }

        public static float ToSingle(byte[] buffer, int bufferOffset)
        {
            return BitConverter.ToSingle(buffer, bufferOffset);
        }

        public static float ToSingle(byte[] buffer, ref int bufferOffset)
        {
            float num = BitConverter.ToSingle(buffer, bufferOffset);
            bufferOffset += BitConverter.GetBytes(num).Length;
            return num;
        }

        public static string ToString(byte[] buffer)
        {
            return ToString(buffer, 0);
        }

        public static string ToString(byte[] buffer, ref int offset)
        {
            int count = Read7BitEncodedInt(buffer, ref offset);
            if (count > (buffer.Length - offset))
            {
                count = buffer.Length - offset;
            }
            if (count <= 0)
            {
                return string.Empty;
            }
            string str = _encoding.GetString(buffer, offset, count);
            offset += count;
            return str;
        }

        public static string ToString(byte[] buffer, int offset)
        {
            return ToString(buffer, ref offset);
        }

        public static ushort ToUInt16(byte[] buffer)
        {
            return (ushort) (buffer[0] | (buffer[1] << 8));
        }

        public static ushort ToUInt16(byte[] buffer, ref int bufferOffset)
        {
            return (ushort) (buffer[bufferOffset++] | (buffer[bufferOffset++] << 8));
        }

        public static ushort ToUInt16(byte[] buffer, int bufferOffset)
        {
            return (ushort) (buffer[bufferOffset] | (buffer[bufferOffset + 1] << 8));
        }

        public static ushort ToUInt16Net(byte[] buffer, ref int bufferOffset)
        {
            return (ushort) ((buffer[bufferOffset++] << 8) | buffer[bufferOffset++]);
        }

        public static ushort ToUInt16Net(byte[] buffer, int bufferOffset)
        {
            return (ushort) ((buffer[bufferOffset] << 8) | buffer[bufferOffset + 1]);
        }

        public static ushort ToUInt24(byte[] buffer)
        {
            return (ushort) ((buffer[0] | (buffer[1] << 8)) | (buffer[2] << 0x10));
        }

        public static ushort ToUInt24(byte[] buffer, ref int bufferOffset)
        {
            return (ushort) ((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10));
        }

        public static ushort ToUInt24(byte[] buffer, int bufferOffset)
        {
            return (ushort) ((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10));
        }

        public static ushort ToUInt24Net(byte[] buffer, int bufferOffset)
        {
            return (ushort) (((buffer[bufferOffset++] << 0x10) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
        }

        public static ushort ToUInt24Net(byte[] buffer, ref int bufferOffset)
        {
            return (ushort) (((buffer[bufferOffset++] << 0x10) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
        }

        public static uint ToUInt32(byte[] buffer)
        {
            return (uint) (((buffer[0] | (buffer[1] << 8)) | (buffer[2] << 0x10)) | (buffer[3] << 0x18));
        }

        public static uint ToUInt32(byte[] buffer, int bufferOffset)
        {
            return (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
        }

        public static uint ToUInt32(byte[] buffer, ref int bufferOffset)
        {
            return (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
        }

        public static uint ToUInt32Net(byte[] buffer, ref int offset)
        {
            return (uint) ((((buffer[offset++] << 0x18) | (buffer[offset++] << 0x10)) | (buffer[offset++] << 8)) | buffer[offset++]);
        }

        public static uint ToUInt32Net(byte[] buffer, int offset = 0)
        {
            return (uint) ((((buffer[offset++] << 0x18) | (buffer[offset++] << 0x10)) | (buffer[offset++] << 8)) | buffer[offset++]);
        }

        public static ulong ToUInt64(byte[] buffer)
        {
            uint num = (uint) (((buffer[0] | (buffer[1] << 8)) | (buffer[2] << 0x10)) | (buffer[3] << 0x18));
            uint num2 = (uint) (((buffer[4] | (buffer[5] << 8)) | (buffer[6] << 0x10)) | (buffer[7] << 0x18));
            return ((num2 << 0x20) | num);
        }

        public static ulong ToUInt64(byte[] buffer, ref int bufferOffset)
        {
            uint num = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            uint num2 = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            return ((num2 << 0x20) | num);
        }

        public static ulong ToUInt64(byte[] buffer, int bufferOffset)
        {
            uint num = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            uint num2 = (uint) (((buffer[bufferOffset++] | (buffer[bufferOffset++] << 8)) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 0x18));
            return ((num2 << 0x20) | num);
        }

        public static ulong ToUInt64Net(ulong num)
        {
            ulong num2 = 0L;
            num2 |= (num & 0xffL) << 0x38;
            num2 |= ((num >> 8) & 0xffL) << 0x30;
            num2 |= ((num >> 0x10) & 0xffL) << 40;
            num2 |= ((num >> 0x18) & 0xffL) << 0x20;
            num2 |= ((num >> 0x20) & 0xffL) << 0x18;
            num2 |= ((num >> 40) & 0xffL) << 0x10;
            num2 |= ((num >> 0x30) & 0xffL) << 8;
            return (num2 | ((num >> 0x38) & ((ulong) 0xffL)));
        }

        public static ulong ToUInt64Net(byte[] buffer, int bufferOffset)
        {
            uint num = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            uint num2 = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            return (num2 | (num << 0x20));
        }

        public static ulong ToUInt64Net(byte[] buffer, ref int bufferOffset)
        {
            uint num = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            uint num2 = (uint) ((((buffer[bufferOffset++] << 0x18) | (buffer[bufferOffset++] << 0x10)) | (buffer[bufferOffset++] << 8)) | buffer[bufferOffset++]);
            return (num2 | (num << 0x20));
        }

        public static void Write(bool value, byte[] ptr)
        {
            ptr[0] = value ? ((byte) 1) : ((byte) 0);
        }

        public static void Write(byte value, byte[] ptr)
        {
            ptr[0] = value;
        }

        public static void Write(double value, byte[] buffer)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Copy(bytes, 0, buffer, 0, bytes.Length);
        }

        public static void Write(int value, byte[] buffer)
        {
            buffer[0] = (byte) value;
            buffer[1] = (byte) (value >> 8);
            buffer[2] = (byte) (value >> 0x10);
            buffer[3] = (byte) (value >> 0x18);
        }

        public static void Write(long value, byte[] buffer)
        {
            buffer[0] = (byte) value;
            buffer[1] = (byte) (value >> 8);
            buffer[2] = (byte) (value >> 0x10);
            buffer[3] = (byte) (value >> 0x18);
            buffer[4] = (byte) (value >> 0x20);
            buffer[5] = (byte) (value >> 40);
            buffer[6] = (byte) (value >> 0x30);
            buffer[7] = (byte) (value >> 0x38);
        }

        public static void Write(float value, byte[] buffer)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Copy(bytes, 0, buffer, 0, bytes.Length);
        }

        public static void Write(string value, byte[] buffer)
        {
            Write(value, buffer, 0);
        }

        public static void Write(ushort value, byte[] buffer)
        {
            buffer[0] = (byte) value;
            buffer[1] = (byte) (value >> 8);
        }

        public static void Write(uint value, byte[] buffer)
        {
            buffer[0] = (byte) value;
            buffer[1] = (byte) (value >> 8);
            buffer[2] = (byte) (value >> 0x10);
            buffer[3] = (byte) (value >> 0x18);
        }

        public static void Write(ulong value, byte[] buffer)
        {
            buffer[0] = (byte) value;
            buffer[1] = (byte) (value >> 8);
            buffer[2] = (byte) (value >> 0x10);
            buffer[3] = (byte) (value >> 0x18);
            buffer[4] = (byte) (value >> 0x20);
            buffer[5] = (byte) (value >> 40);
            buffer[6] = (byte) (value >> 0x30);
            buffer[7] = (byte) (value >> 0x38);
        }

        public static void Write(bool value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = value ? ((byte) 1) : ((byte) 0);
        }

        public static void Write(bool value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset] = value ? ((byte) 1) : ((byte) 0);
        }

        public static void Write(byte value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset] = value;
        }

        public static void Write(byte value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = value;
        }

        public static void Write(double value, byte[] buffer, int bufferOffset)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Copy(bytes, 0, buffer, bufferOffset, bytes.Length);
        }

        public static void Write(double value, byte[] buffer, ref int bufferOffset)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Copy(bytes, 0, buffer, bufferOffset, bytes.Length);
            bufferOffset += bytes.Length;
        }

        public static void Write(short value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
        }

        public static void Write(short value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
        }

        public static void Write(int value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
        }

        public static void Write(int value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
        }

        public static void Write(long value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
            buffer[bufferOffset++] = (byte) (value >> 0x20);
            buffer[bufferOffset++] = (byte) (value >> 40);
            buffer[bufferOffset++] = (byte) (value >> 0x30);
            buffer[bufferOffset++] = (byte) (value >> 0x38);
        }

        public static void Write(long value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
            buffer[bufferOffset++] = (byte) (value >> 0x20);
            buffer[bufferOffset++] = (byte) (value >> 40);
            buffer[bufferOffset++] = (byte) (value >> 0x30);
            buffer[bufferOffset++] = (byte) (value >> 0x38);
        }

        public static void Write(float value, byte[] buffer, int bufferOffset)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Copy(bytes, 0, buffer, bufferOffset, bytes.Length);
        }

        public static void Write(float value, byte[] buffer, ref int bufferOffset)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Copy(bytes, 0, buffer, bufferOffset, bytes.Length);
            bufferOffset += bytes.Length;
        }

        public static void Write(string value, byte[] buffer, ref int bufferOffset)
        {
            if (value == null)
            {
                value = string.Empty;
            }
            int byteCount = _encoding.GetByteCount(value);
            if (byteCount > (buffer.Length - ((byteCount > 0xff) ? 2 : 1)))
            {
                byteCount = (buffer.Length - bufferOffset) - ((byteCount > 0xff) ? 2 : 1);
                Write7BitEncodedInt(buffer, ref bufferOffset, byteCount);
                Array.Copy(_encoding.GetBytes(value), 0, buffer, bufferOffset, byteCount);
            }
            else
            {
                Write7BitEncodedInt(buffer, ref bufferOffset, byteCount);
                _encoding.GetBytes(value, 0, value.Length, buffer, bufferOffset);
            }
            bufferOffset += byteCount;
        }

        public static void Write(ushort value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
        }

        public static void Write(uint value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
        }

        public static void Write(byte[] value, byte[] buffer, ref int bufferOffset)
        {
            if (value != null)
            {
                Array.Copy(value, 0, buffer, bufferOffset, value.Length);
                bufferOffset += value.Length;
            }
        }

        public static void Write(ushort value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
        }

        public static void Write(ulong value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
            buffer[bufferOffset++] = (byte) (value >> 0x20);
            buffer[bufferOffset++] = (byte) (value >> 40);
            buffer[bufferOffset++] = (byte) (value >> 0x30);
            buffer[bufferOffset++] = (byte) (value >> 0x38);
        }

        public static void Write(ulong value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
            buffer[bufferOffset++] = (byte) (value >> 0x20);
            buffer[bufferOffset++] = (byte) (value >> 40);
            buffer[bufferOffset++] = (byte) (value >> 0x30);
            buffer[bufferOffset++] = (byte) (value >> 0x38);
        }

        public static void Write(byte[] value, byte[] buffer, int bufferOffset)
        {
            if (value != null)
            {
                Array.Copy(value, 0, buffer, bufferOffset, value.Length);
            }
        }

        public static void Write(string value, byte[] buffer, int bufferOffset)
        {
            int byteCount = _encoding.GetByteCount(value);
            if (byteCount > ((buffer.Length - bufferOffset) - ((byteCount > 0xff) ? 2 : 1)))
            {
                byteCount = (buffer.Length - bufferOffset) - ((byteCount > 0xff) ? 2 : 1);
                Write7BitEncodedInt(buffer, ref bufferOffset, byteCount);
                Array.Copy(_encoding.GetBytes(value), 0, buffer, bufferOffset, byteCount);
            }
            else
            {
                Write7BitEncodedInt(buffer, ref bufferOffset, byteCount);
                _encoding.GetBytes(value, 0, value.Length, buffer, bufferOffset);
            }
        }

        public static void Write(uint value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
            buffer[bufferOffset++] = (byte) (value >> 0x18);
        }

        public static void Write(byte[] value, int valueOffset, int writeLen, byte[] buffer, int bufferOffset)
        {
            if (value != null)
            {
                Array.Copy(value, valueOffset, buffer, bufferOffset, writeLen);
            }
        }

        public static void Write(byte[] value, int valueOffset, int writeLen, byte[] buffer, ref int bufferOffset)
        {
            if (value != null)
            {
                Array.Copy(value, valueOffset, buffer, bufferOffset, writeLen);
                bufferOffset += writeLen;
            }
        }

        public static void Write24(int value, byte[] buffer)
        {
            buffer[0] = (byte) value;
            buffer[1] = (byte) (value >> 8);
            buffer[2] = (byte) (value >> 0x10);
        }

        public static void Write24(int value, byte[] buffer, int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
        }

        public static void Write24(int value, byte[] buffer, ref int bufferOffset)
        {
            buffer[bufferOffset++] = (byte) value;
            buffer[bufferOffset++] = (byte) (value >> 8);
            buffer[bufferOffset++] = (byte) (value >> 0x10);
        }

        public static void Write24Net(int value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void Write24Net(int value, byte[] buffer, int offset = 0)
        {
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void Write24Net(uint value, byte[] buffer, int offset = 0)
        {
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void Write24Net(uint value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        private static void Write7BitEncodedInt(byte[] buffer, ref int offset, int value)
        {
            uint num = (uint) value;
            while (num >= 0x80)
            {
                buffer[offset++] = (byte) (num | 0x80);
                num = num >> 7;
            }
            Write((byte) num, buffer, (int) offset++);
        }

        public static void WriteBCD(string bcdString, int start, int len, byte[] result, int offset)
        {
            int num = len / 2;
            if ((len % 2) != 0)
            {
                num++;
            }
            for (int i = 0; i < num; i++)
            {
                byte num3 = 0x30;
                int num4 = (i * 2) + start;
                if ((num4 + 1) < bcdString.Length)
                {
                    num3 = (byte) ((((bcdString[num4] - '0') % 10) * 0x10) + (bcdString[num4 + 1] - '0'));
                }
                else if (num4 < bcdString.Length)
                {
                    num3 = (byte) (((bcdString[num4] - '0') % 10) * 0x10);
                }
                result[offset++] = num3;
            }
        }

        public static void WriteBCD(string bcdString, int start, int len, byte[] result, ref int offset)
        {
            int num = len / 2;
            for (int i = 0; i < num; i++)
            {
                byte num3 = 0x30;
                int num4 = (i * 2) + start;
                if ((num4 + 1) < bcdString.Length)
                {
                    num3 = (byte) ((((bcdString[num4] - '0') % 10) * 0x10) + (bcdString[num4 + 1] - '0'));
                }
                else if (num4 < bcdString.Length)
                {
                    num3 = (byte) (((bcdString[num4] - '0') % 10) * 0x10);
                }
                result[offset++] = num3;
            }
        }
        public static byte[] StringToByteArrayFastest(string hex)
        {
            if (hex.Length % 2 == 1)
                throw new Exception("The binary key cannot have an odd number of digits");

            byte[] arr = new byte[hex.Length >> 1];

            for (int i = 0; i < hex.Length >> 1; ++i)
            {
                arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }

            return arr;
        }
        public static byte[] WriteStringToByteArrayFastest(string hex , byte[] result , ref int offset)
        {
            if (hex.Length % 2 == 1)
                throw new Exception("The binary key cannot have an odd number of digits");

            byte[] arr = new byte[hex.Length >> 1];

            for (int i = 0; i < hex.Length >> 1; ++i, ++offset)
            {
                result[offset] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }
            return arr;
        }
        public static byte[] WriteStringToByteArrayFastest(string hex, int start, int len, byte[] result, ref int offset)
        {
            if ((len-start) % 2 == 1)
                throw new Exception("The binary key cannot have an odd number of digits");

            byte[] arr = new byte[hex.Length >> 1];

            for (int i = len; i < start >> 1; ++i, ++offset)
            {
                result[i + offset] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }
            return arr;
        }
        public static int GetHexVal(char hex)
        {
            int val = (int)hex;
            //For uppercase A-F letters:
            return val - (val < 58 ? 48 : 55);
            //For lowercase a-f letters:
            //return val - (val < 58 ? 48 : 87);
            //Or the two combined, but a bit slower:
            //return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
        }

        public static void WriteBit(ref byte target, int index, bool value)
        {
            if (!value)
            {
                target = (byte) (target & ~(((int) 1) << index));
            }
            else
            {
                target = (byte) (target | (((int) 1) << index));
            }
        }

        public static void WriteBit(ref short target, int index, bool value)
        {
            if (!value)
            {
                target = (short) (target & ~(((int) 1) << index));
            }
            else
            {
                target = (short) (target | ((short) (((int) 1) << index)));
            }
        }

        public static void WriteBit(ref int target, int index, bool value)
        {
            if (!value)
            {
                target &= ~(((int) 1) << index);
            }
            else
            {
                target |= ((int) 1) << index;
            }
        }

        public static void WriteBit(ref long target, int index, bool value)
        {
            if (!value)
            {
                target &= ~(((long) 1L) << index);
            }
            else
            {
                target |= ((long) 1L) << index;
            }
        }

        public static void WriteBit(ref ushort target, int index, bool value)
        {
            if (!value)
            {
                target = (ushort) (target & ~(((int) 1) << index));
            }
            else
            {
                target = (ushort) (target | (((int) 1) << index));
            }
        }

        public static void WriteBit(ref uint target, int index, bool value)
        {
            if (!value)
            {
                target &=(uint) ~(((int) 1) << index);
            }
            else
            {
                target |= (uint)((int) 1) << index;
            }
        }

        public static void WriteBit(ref ulong target, int index, bool value)
        {
            if (!value)
            {
                target = (ulong) (target & (ulong)~(((long) 1L) << index));
            }
            else
            {
                target = (ulong) (target | (ulong)(((long) 1L) << index));
            }
        }

        public static void WriteByte(ref char target, int index, byte value)
        {
            target = (char) ((ushort) (target & ((ushort) ~(((int) 0xff) << (8 * index)))));
            target = (char) ((ushort) (target | ((ushort) (value << (index * 8)))));
        }

        public static void WriteByte(ref short target, int index, byte value)
        {
            target = (short) (target & ((short) ~(((int) 0xff) << (8 * index))));
            target = (short) (target | ((short) (value << (index * 8))));
        }

        public static void WriteByte(ref int target, int index, byte value)
        {
            target &= ~(((int) 0xff) << (8 * index));
            target |= value << (8 * index);
        }

        public static void WriteByte(ref long target, int index, byte value)
        {
            target &= ~(((long) 0xffL) << (8 * index));
            target |= (byte)(value << (index * 8));
        }

        public static void WriteByte(ref ushort target, int index, byte value)
        {
            target = (ushort) (target & ((ushort) ~(((int) 0xff) << (8 * index))));
            target = (ushort) (target | ((ushort) (value << (index * 8))));
        }

        public static void WriteByte(ref uint target, int index, byte value)
        {
            target &= (uint)~(((int) 0xff) << (8 * index));
            target |= (uint)value << (index * 8);
        }

        public static void WriteByte(ref ulong target, int index, byte value)
        {
            target = (ulong) (target & (uint)~(((long) 0xffL) << (8 * index)));
            target |= (ulong)(value << (index * 8));
        }

        public static void WriteCharString(string content, int start, int len, byte[] buffer, ref int offset)
        {
            if ((content != null) && !(content == string.Empty))
            {
                for (int i = 0; i < len; i++)
                {
                    buffer[offset++] = (byte) content[i + start];
                }
            }
        }

        public static void WriteCharString(string content, int start, int len, byte[] buffer, int offset)
        {
            if ((content != null) && !(content == string.Empty))
            {
                for (int i = 0; i < len; i++)
                {
                    buffer[offset++] = (byte) content[i + start];
                }
            }
        }

        public static void WriteNet(int value, byte[] buffer, int offset)
        {
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(int value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(long value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 0x38);
            buffer[offset++] = (byte) (value >> 0x30);
            buffer[offset++] = (byte) (value >> 40);
            buffer[offset++] = (byte) (value >> 0x20);
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(long value, byte[] buffer, int offset)
        {
            buffer[offset++] = (byte) (value >> 0x38);
            buffer[offset++] = (byte) (value >> 0x30);
            buffer[offset++] = (byte) (value >> 40);
            buffer[offset++] = (byte) (value >> 0x20);
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(ushort value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(ushort value, byte[] buffer, int offset)
        {
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(uint value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(uint value, byte[] buffer, int offset)
        {
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(ulong value, byte[] buffer, ref int offset)
        {
            buffer[offset++] = (byte) (value >> 0x38);
            buffer[offset++] = (byte) (value >> 0x30);
            buffer[offset++] = (byte) (value >> 40);
            buffer[offset++] = (byte) (value >> 0x20);
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }

        public static void WriteNet(ulong value, byte[] buffer, int offset)
        {
            buffer[offset++] = (byte) (value >> 0x38);
            buffer[offset++] = (byte) (value >> 0x30);
            buffer[offset++] = (byte) (value >> 40);
            buffer[offset++] = (byte) (value >> 0x20);
            buffer[offset++] = (byte) (value >> 0x18);
            buffer[offset++] = (byte) (value >> 0x10);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) value;
        }
        public static byte[] Combine(byte[] first, byte[] second)
        {
            if (first == null) return second;
            if (second == null) return first;
            byte[] ret = new byte[first.Length + second.Length];
            Buffer.BlockCopy(first, 0, ret, 0, first.Length);
            Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
            return ret;
        }

        public static byte[] Combine(byte[] first, byte[] second, byte[] third)
        {
            byte[] ret = new byte[first.Length + second.Length + third.Length];
            Buffer.BlockCopy(first, 0, ret, 0, first.Length);
            Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
            Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                             third.Length);
            return ret;
        }

    }
}

